package net.cardgame.orcalecard;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;

import jp.jma.oraclecard.R;
import net.cardgame.oraclecard.billingutils.IabHelper;
import net.cardgame.oraclecard.billingutils.IabResult;
import net.cardgame.oraclecard.billingutils.Inventory;
import net.cardgame.oraclecard.billingutils.Purchase;
import net.cardgame.oraclecard.common.MySwitch;
import net.cardgame.orcalecard.bean.DeckBean;
import net.cardgame.orcalecard.bean.SettingApp;
import net.cardgame.orcalecard.pref.SecurePreferences;
import net.cardgame.orcalecard.utils.ConstantValue;
import net.cardgame.orcalecard.utils.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class SettingActiviy extends Activity implements OnClickListener,
		OnCheckedChangeListener {
	SettingApp setting;
	SecurePreferences appPreferences;
	ArrayList<DeckBean> listDeckBean;

	LinearLayout wait_layout;

	// / BILLING

	static final String BILLING_TAG = "DECK BILLING";

	static final int PURCHASE_REQUEST = 10001;

	// The helper object
	IabHelper mHelper;

	// public key in developer console
	String base64EncodedPublicKey = "CONSTRUCT_YOUR_KEY_AND_PLACE_IT_HERE";

	boolean isBillingSupport = false;

	boolean isWait = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.setting_app_layout);
		appPreferences = new SecurePreferences(this,
				ConstantValue.APP_PREFERENCES,
				ConstantValue.PREFERENCES_SECRET_KEY, true);
		getStatus();
		loadSettingApp();
		MySwitch switchJumpCard = (MySwitch) findViewById(R.id.switchJumcard);
		MySwitch switchAdvise = (MySwitch) findViewById(R.id.switchAdviseCard);
		MySwitch switchSound = (MySwitch) findViewById(R.id.switchSound);
		switchJumpCard.setOnCheckedChangeListener(this);
		switchAdvise.setOnCheckedChangeListener(this);
		switchSound.setOnCheckedChangeListener(this);
		switchJumpCard.setChecked(setting.jumCard);
		switchAdvise.setChecked(setting.adviseCard);
		switchSound.setChecked(setting.sound);
		findViewById(R.id.btn_help_setting).setOnClickListener(this);
		findViewById(R.id.btn_back_setting).setOnClickListener(this);
		findViewById(R.id.layout_confirm_restore).setOnClickListener(this);
		findViewById(R.id.layout_sortTop).setOnClickListener(this);
		findViewById(R.id.layout_special).setOnClickListener(this);

		wait_layout = (LinearLayout) findViewById(R.id.layout_wait_restore);

		// / INIT BILLING
		base64EncodedPublicKey = this.getResources().getString(
				R.string.app_public_key);
		// Create the helper, passing it our context and the public key to
		// verify signatures with
		Utils.ELog(BILLING_TAG, "Creating IAB helper.");
		mHelper = new IabHelper(this, base64EncodedPublicKey);

		// enable debug logging (for a production application, you should set
		// this to false).
		mHelper.enableDebugLogging(true);

	}

	void getStatus() {
		// get config app string
		Gson gson = new Gson();
		Type listOfDeckBean = new TypeToken<ArrayList<DeckBean>>() {
		}.getType();
		String listSaved = appPreferences
				.getString(ConstantValue.CONFIG_DECKBEAN_KEY);
		listDeckBean = gson.fromJson(listSaved, listOfDeckBean);
	}

	void loadSettingApp() {
		Gson gson = new Gson();
		Type SettingAppType = new TypeToken<SettingApp>() {
		}.getType();
		if (appPreferences.containsKey(ConstantValue.SETTING_KEY)) {
			String strSetting = appPreferences
					.getString(ConstantValue.SETTING_KEY);
			// Utils.ELog("str_History", strHistory);
			setting = gson.fromJson(strSetting, SettingAppType);
		}

	}

	/**
	 * Save status DeckBean
	 */
	private void saveStatus() {
		SecurePreferences appPreferences = new SecurePreferences(this,
				ConstantValue.APP_PREFERENCES,
				ConstantValue.PREFERENCES_SECRET_KEY, true);
		Gson gson = new Gson();
		Type listOfDeckBean = new TypeToken<ArrayList<DeckBean>>() {
		}.getType();
		String save = gson.toJson(listDeckBean, listOfDeckBean);
		appPreferences.put(ConstantValue.CONFIG_DECKBEAN_KEY, save);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (isWait) {
			return;
		}
		switch (v.getId()) {
		case R.id.btn_help_setting:
			Intent intent = new Intent(this, HelpActivity.class);
			intent.putExtra(HelpActivity.KEY_HELP_INDEX, 3);
			startActivityForResult(intent, 0);
			overridePendingTransition(R.anim.slide_in_right,
					R.anim.slide_out_left);
			break;
		case R.id.btn_back_setting:
			this.finish();
			break;

		case R.id.layout_confirm_restore:
			dialogRestore();
			break;
		case R.id.layout_sortTop:
			Intent intentSort = new Intent(this, SettingSortActivity.class);
			intentSort.putExtra("sort_by", setting.sortToppage);
			startActivityForResult(intentSort, 1);
			overridePendingTransition(R.anim.slide_in_right,
					R.anim.slide_out_left);
			break;
		case R.id.layout_special:
			startActivityForResult(new Intent(this,
					SettingSpecialActivity.class), 0);
			overridePendingTransition(R.anim.slide_in_right,
					R.anim.slide_out_left);
			break;
		default:
			break;
		}
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		// TODO Auto-generated method stub

		switch (buttonView.getId()) {
		case R.id.switchJumcard:
			setting.jumCard = isChecked;
			saveSetting();
			break;
		case R.id.switchAdviseCard:
			setting.adviseCard = isChecked;
			saveSetting();
			break;
		case R.id.switchSound:
			setting.sound = isChecked;
			saveSetting();
			break;
		default:
			break;
		}
	}

	void saveSetting() {
		Gson gson = new Gson();
		Type SettingAppType = new TypeToken<SettingApp>() {
		}.getType();
		String save = gson.toJson(setting, SettingAppType);
		appPreferences.put(ConstantValue.SETTING_KEY, save);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
		if (requestCode == 1) {
			setting.sortToppage = resultCode;
			saveSetting();
		}
	}

	private void dialogRestore() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		// builder.setTitle("hỏi thoát chương trình");
		String message = getResources().getString(
				R.string.dialog_restore_message);
		builder.setMessage(message);
		builder.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				billingRestore();
				// finish();
			}
		});
		builder.setCancelable(false);
		builder.create().show();
	}

	private void billingRestore() {

		setWaitScreen(true);
		// Start setup. This is asynchronous and the specified listener
		// will be called once setup completes.
		Utils.ELog(BILLING_TAG, "Starting setup.");
		if (!isBillingSupport) {
			mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
				public void onIabSetupFinished(IabResult result) {
					Utils.ELog(BILLING_TAG, "Setup finished.");
					if (!result.isSuccess()) {
						// Oh noes, there was a problem.
						Utils.ELog(BILLING_TAG,
								"Problem setting up in-app billing: " + result);
						setWaitScreen(false);
						return;
					}
					// Hooray, IAB is fully set up. Now, let's get an inventory
					// of
					// stuff we own.
					Utils.ELog(BILLING_TAG,
							"Setup successful. Querying inventory.");
					isBillingSupport = true;
					mHelper.queryInventoryAsync(mGotInventoryListener);
				}
			});
		} else {
			Utils.ELog(BILLING_TAG, "billing support. Querying inventory.");
			mHelper.queryInventoryAsync(mGotInventoryListener);
		}
	}

	// Listener that's called when we finish querying the items and
	// subscriptions we own
	// Lấy thông tin các item mà user đã mua (sở hữu)
	IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
		public void onQueryInventoryFinished(IabResult result,
				Inventory inventory) {
			Utils.ELog(BILLING_TAG, "Query inventory finished.");
			if (result.isFailure()) {
				Utils.ELog(BILLING_TAG, "Failed to query inventory: " + result);
				setWaitScreen(false);
				return;
			}

			Utils.ELog(BILLING_TAG, "Query inventory was successful.");
			Utils.ELog(BILLING_TAG,
					"Query inventory info: " + inventory.toString());

			for (int i = 0; i < listDeckBean.size(); i++) {
				Purchase testPurchase = inventory.getPurchase(listDeckBean
						.get(i).inAppPurchaseId);

				Utils.ELog(BILLING_TAG,
						"item inventory info: "
								+ listDeckBean.get(i).inAppPurchaseId);

				if (testPurchase != null
						&& verifyDeveloperPayload(testPurchase)) {
					Utils.ELog(BILLING_TAG, " deck already bought id: "
							+ listDeckBean.get(i).inAppPurchaseId);
					listDeckBean.get(i).isUnlock = true;
					Date purchaseDate = new Date(testPurchase.getPurchaseTime());
					listDeckBean.get(i).buyDate = purchaseDate;
				}
			}
			saveStatus();
			setWaitScreen(false);
			setResult(RESULT_OK);
		}
	};

	/** Verifies the developer payload of a purchase. */
	// Xác thực đoạn pay load trả về
	boolean verifyDeveloperPayload(Purchase p) {
		String payloadReturn = p.getDeveloperPayload();

		/*
		 * TODO: verify that the developer payload of the purchase is correct.
		 * It will be the same one that you sent when initiating the purchase.
		 * 
		 * WARNING: Locally generating a random string when starting a purchase
		 * and verifying it here might seem like a good approach, but this will
		 * fail in the case where the user purchases an item on one device and
		 * then uses your app on a different device, because on the other device
		 * you will not have access to the random string you originally
		 * generated.
		 * 
		 * So a good developer payload has these characteristics:
		 * 
		 * 1. If two different users purchase an item, the payload is different
		 * between them, so that one user's purchase can't be replayed to
		 * another user.
		 * 
		 * 2. The payload must be such that you can verify it even when the app
		 * wasn't the one who initiated the purchase flow (so that items
		 * purchased by the user on one device work on other devices owned by
		 * the user).
		 * 
		 * Using your own server to store and verify developer payloads across
		 * app installations is recommended.
		 */

		return true;
	}

	// Tắt/Bật màn hình chờ
	void setWaitScreen(boolean set) {
		wait_layout.setVisibility(set ? View.VISIBLE : View.GONE);
		isWait = set ? true : false;
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		// very important:
		Utils.ELog(BILLING_TAG, "Destroying helper.");
		if (mHelper != null)
			mHelper.dispose();
		mHelper = null;
	}
}
